<?php

namespace app\controller\api\rke;

use app\BaseController;
use app\common\service\redis\PoolRedis;
use app\model\AdminStaff;
use app\model\AdminStaffIcCard;
use app\util\rke\Tool;
use think\App;
use think\facade\Log;
use think\facade\Queue;

/**
 * 门禁控制器
 */
class Acs extends BaseController
{
    private $school_id; //学校id
    private $door_location; //门禁位置
    private static int $is_transition; // IC卡号16进制格式，进行两两转换 1:转换 0:不转换 * 弃用

    public function __construct(App $app)
    {
        parent::__construct($app);
        $getArr = $this->request->get();
        $this->school_id = empty($getArr['school_id']) ? 0 : $getArr['school_id'];
        $this->door_location = empty($getArr['door_location']) ? 0 : $getArr['door_location'];
        self::$is_transition = isset($getArr['is_transition']) && $getArr['is_transition'] == 1 ? 1 : 0;
    }

    /**
     * 刷卡请求
     * 返回允许或拒绝开门
     */
    public function SearchCardAcs()
    {
        $jsonData = Tool::GetPostArray();
        $acsRes = 0; //开门状态 1:允许打开 0:拒绝打开
        $actIndex = $jsonData['Reader'] == 1 ? 1 : 0; //进出方向 0:进 1:出 2:报警
        try {
            Log::error("打印门禁数据: " . json_encode($jsonData));
            $staff_id = $this->checkCardReturnID($jsonData, $isFace);
            // 为了配合人脸机的卡号规则,人脸机的卡号就是用户ID
            // 人脸识别数据
            if ($isFace) {
                if ($staff_id !== false && is_numeric($staff_id)) {
                    $acsRes = 1;
                    /*
                     * {"type":"0","Reader":"0","DataLen":"0","Index":"18934","Serial":"8P8038","Status":"00","Input":"0000","Ver":"168","ID":"8P8038","IP":"192.168.2.38","MAC":"0004A3048790","Card":"15270"}
                     */
                    //Log::error('加入队列->记录门禁上传的人脸开门记录');
                    //记录门禁上传的人脸开门记录
                    Queue::push('app\task\job\SchoolRkeRecord@fire', [
                        'serial' => $jsonData['Serial'],
                        'card' => "",
                        'card_name' => Tool::$card_type[13],
                        'card_type' => 13,
                        'acs_res' => $acsRes,
                        'act_index' => $actIndex,
                        'time' => time(),
                        'staff_id' => $jsonData['Card']
                    ]);
                }
            }
            // 其它数据
            else {
                if ($staff_id !== false && is_numeric($staff_id)) {
                    $acsRes = 1;
                    /*
                     * {"type":"0","Reader":"1","DataLen":"0","Index":"25760","Serial":"8P8033","Status":"00","Input":"0000","Ver":"168","ID":"8P8033","IP":"192.168.2.33","MAC":"0004A37FF913","Card":"1160142339"}
                     */
                    //Log::error('加入队列->记录门禁上传的开门记录');
                    //记录门禁上传的开门记录
                    Queue::push('app\task\job\SchoolRkeRecord@fire', [
                        'serial' => $jsonData['Serial'],
                        'card' => $jsonData['Card'],
                        'card_name' => Tool::$card_type[$jsonData['type']],
                        'card_type' => $jsonData['type'],
                        'acs_res' => $acsRes,
                        'act_index' => $actIndex,
                        'time' => time(),
                        'staff_id' => $staff_id
                    ]);
                }
            }
        } catch (\Exception $e) {
            Log::error("门禁异常:" . $e->getMessage());
        }
        //应答
        $data = Tool::GetAnswer($acsRes, $actIndex);
        //不编码中文
        $msg = json_encode($data, JSON_UNESCAPED_UNICODE);
        //转换成gb2312解决WEB页面乱码问题
        $msg = iconv("UTF-8", "gb2312", $msg);
        Log::error("门禁认证结果:" . $msg);
        return $msg;
    }

    /**
     * 心跳响应
     * @return false|string|\think\response\Json
     */
    public function Status()
    {
        if ($this->request->method() === 'POST') {
            $reqData = Tool::GetPostArray();
            Tool::SetMethod('POST');
        } else {
            $reqData = $this->request->get();
            Tool::SetMethod('GET');
        }
        try {
            if (empty($reqData['Now'])) {
                return json([]);
            }
            $reqData['Now'] = strtotime(round(bcdiv($reqData['Now'], 100), 0));
            Queue::push('app\task\job\SchoolDevice@fire', [
                'school_id' => $this->school_id,
                'serial_type' => 1,
                'door_location' => $this->door_location,
                'serial' => $reqData['Serial'],
                'device_id' => $reqData['ID'],
                'door_status' => $reqData['Status'],
                'ip' => $reqData['IP'],
                'mac' => $reqData['MAC'],
                'heart_time' => $reqData['Now'],
            ]);
            if (bcsub($reqData['Now'], time()) < -30 || bcsub($reqData['Now'], time()) > 30) {
                return json_encode(['Key' => $reqData['Key'], 'Now' => date('YmdHis0w') + 1], JSON_UNESCAPED_UNICODE);  //不编码中文
            } else {
                return json_encode(['Key' => $reqData['Key']], JSON_UNESCAPED_UNICODE);  //不编码中文
            }
        } catch (\Exception $e) {
            return json_encode(['Key' => $reqData['Key']], JSON_UNESCAPED_UNICODE);  //不编码中文
        }
    }

    public static function getCardCacheKey(&$data, &$field = '', &$delete = false)
    {
        $key = '';
        switch ($data['type']) {
            case '0'://刷卡数据
                $key = "smartCards";
                // IC卡号格式转换
                $field = self::$is_transition == 1 ? icCardToLeQiFormat($data['Card']) : $data['Card'];
                break;
            case '1'://二维码
                $data['Card'] = str_replace(array("\r\n", "\n", "\r"), '', $data['Card']);
                $key = "D_LOCKS:" . $data['Card'];
                // $delete = true; // 注释使用一次失效
                break;
            case '2'://密码器
                break;
            case '3'://按钮
                break;
            case '6'://二代证数据
                $chinaCard = Tool::GetInfoByChinacard($data);
                //身份证号 $chinaCard['Card']  姓名 $chinaCard['Name']
                break;
            case '9'://Base64二维码,使用一次后失效
                //解码,替换换行
                $data['Card'] = str_replace(array("\r\n", "\n", "\r"), '', base64_decode($data['Card']));
                $key = "D_LOCKS:" . $data['Card'];
                // $delete = true; // 注释使用一次失效
                break;
            case '10'://指纹数据
                break;
            case '11'://指静脉数据
                break;
            case '12'://RFID卡
                break;
            case '13'://人脸
                break;
            default:
                break;
        }
        return $key;
    }

    // 获取staff id
    private function checkCardReturnID(&$jsonData, &$isFace)
    {
        if ($jsonData['type'] == '0'){//刷卡数据 IC卡或者人脸
            $card = $jsonData['Card'];
            $length = strlen($card);
            if($length < 7) { // 小于7位长度判断用户ID 一百万内
                // 人脸
                $staff = AdminStaff::field('id')
                    ->where(['id' => $card, 'is_delete' => 0, 'school_id' => $this->school_id])
                    ->find();
                if(!empty($staff['id'])){
                    $isFace = true;
                    return $staff['id'];
                }
            } else {
                if($length == 10){ // 10进制读取
                    $card = dechex($card);
                }
                // 正读 反读 10进制 都允许查询
                $icCardArr = [$jsonData['Card'], $card, icCardToLeQiFormat($card)];
                Log::error($icCardArr);
                // IC卡
                $icCard = AdminStaffIcCard::field('staff_id')
                    ->whereIn('ic_card', $icCardArr)
                    ->where(['is_delete' => 0, 'school_id' => $this->school_id])
                    ->find();
                if(!empty($icCard['staff_id'])){
                    $isFace = false;
                    return $icCard['staff_id'];
                }
            }
        } else {
            // 二维码
            $cache_key = self::getCardCacheKey($jsonData, $field, $delete);
            $isFace = false;
            return getRedisCardReturnID($cache_key, $field, $delete);
        }
        return false;
    }
}